#include <compilation/task/PrintTask.h>
#include <functional>
#include <cstdio>


namespace compilation
{


void PrintTask::applyOn(VirtualInstruction &instruction, VirtualAgenda &continuations)
{
  assert(dynamic_cast<const PrintAgenda*>(&continuations));
  PrintAgenda& agenda = (PrintAgenda&) continuations;
  static const std::size_t buffer_size = 10;
  char buffer[buffer_size];
  std::snprintf(buffer, buffer_size, "%3d   ", instruction.getRegistrationIndex());
  agenda.m_out << buffer;
  indent(&agenda.m_out);
  instruction.print(
        agenda.m_out,
        std::bind(&PrintTask::indent, *this, &agenda.m_out, 3));
}


VirtualTask *PrintTask::clone(void) const
{ return new PrintTask(*this); }


void PrintTask::indent(std::ostream* stream, unsigned offset)
{
  for (int shift = m_indent + offset; --shift >= 0;)
    (*stream) << "  ";
}


PrintAgenda::~PrintAgenda(void)
{
  for (VirtualInstruction* iter : m_markedInstruction)
    iter->mark = nullptr;
  m_markedInstruction.clear();
}


void PrintAgenda::markInstructionWith(VirtualInstruction &instruction, VirtualTask &task)
{
  m_markedInstruction.push_back(&instruction);
  instruction.mark = (void*) 1;
}


} // compilation
